import { Polygon, Path, SVG } from '@svgdotjs/svg.js';
import { CONSTANTS } from '../../../constants/constant';

//  节点形状类
export default class Shape {
    constructor(node) {
        this.node = node;
        this.mindMap = node.mindMap;
    }

    //  形状需要的padding
    getShapePadding(width, height, paddingX, paddingY) {
        const shape = this.node.getShape();
        const defaultPaddingX = 15;
        const defaultPaddingY = 5;
        const actWidth = width + paddingX * 2;
        const actHeight = height + paddingY * 2;
        const actOffset = Math.abs(actWidth - actHeight);
        switch (shape) {
            case CONSTANTS.SHAPE.ROUNDED_RECTANGLE:
                return {
                    paddingX: height > width ? (height - width) / 2 : 0,
                    paddingY: 0,
                };
            case CONSTANTS.SHAPE.DIAMOND:
                return {
                    paddingX: width / 2,
                    paddingY: height / 2,
                };
            case CONSTANTS.SHAPE.PARALLELOGRAM:
                return {
                    paddingX: paddingX <= 0 ? defaultPaddingX : 0,
                    paddingY: 0,
                };
            case CONSTANTS.SHAPE.OUTER_TRIANGULAR_RECTANGLE:
                return {
                    paddingX: paddingX <= 0 ? defaultPaddingX : 0,
                    paddingY: 0,
                };
            case CONSTANTS.SHAPE.INNER_TRIANGULAR_RECTANGLE:
                return {
                    paddingX: paddingX <= 0 ? defaultPaddingX : 0,
                    paddingY: 0,
                };
            case CONSTANTS.SHAPE.ELLIPSE:
                return {
                    paddingX: paddingX <= 0 ? defaultPaddingX : 0,
                    paddingY: paddingY <= 0 ? defaultPaddingY : 0,
                };
            case CONSTANTS.SHAPE.CIRCLE:
                return {
                    paddingX: actHeight > actWidth ? actOffset / 2 : 0,
                    paddingY: actHeight < actWidth ? actOffset / 2 : 0,
                };
            default:
                return {
                    paddingX: 0,
                    paddingY: 0,
                };
        }
    }

    //  创建形状节点
    createShape() {
        const shape = this.node.getShape();
        let node = null;
        // 矩形
        if (shape === CONSTANTS.SHAPE.RECTANGLE) {
            node = this.createRect();
        } else if (shape === CONSTANTS.SHAPE.DIAMOND) {
            // 菱形
            node = this.createDiamond();
        } else if (shape === CONSTANTS.SHAPE.PARALLELOGRAM) {
            // 平行四边形
            node = this.createParallelogram();
        } else if (shape === CONSTANTS.SHAPE.ROUNDED_RECTANGLE) {
            // 圆角矩形
            node = this.createRoundedRectangle();
        } else if (shape === CONSTANTS.SHAPE.OCTAGONAL_RECTANGLE) {
            // 八角矩形
            node = this.createOctagonalRectangle();
        } else if (shape === CONSTANTS.SHAPE.OUTER_TRIANGULAR_RECTANGLE) {
            // 外三角矩形
            node = this.createOuterTriangularRectangle();
        } else if (shape === CONSTANTS.SHAPE.INNER_TRIANGULAR_RECTANGLE) {
            // 内三角矩形
            node = this.createInnerTriangularRectangle();
        } else if (shape === CONSTANTS.SHAPE.ELLIPSE) {
            // 椭圆
            node = this.createEllipse();
        } else if (shape === CONSTANTS.SHAPE.CIRCLE) {
            // 圆
            node = this.createCircle();
        }
        return node;
    }

    // 获取节点减去节点边框宽度、hover节点边框宽度后的尺寸
    getNodeSize() {
        const borderWidth = this.node.getBorderWidth();
        let { width, height } = this.node;
        width -= borderWidth;
        height -= borderWidth;
        return {
            width,
            height,
        };
    }

    // 创建路径节点
    createPath(pathStr) {
        const { customCreateNodePath } = this.mindMap.opt;
        if (customCreateNodePath) {
            return SVG(customCreateNodePath(pathStr));
        }
        return new Path().plot(pathStr);
    }

    // 创建多边形节点
    createPolygon(points) {
        const { customCreateNodePolygon } = this.mindMap.opt;
        if (customCreateNodePolygon) {
            return SVG(customCreateNodePolygon(points));
        }
        return new Polygon().plot(points);
    }

    // 创建矩形
    createRect() {
        let { width, height } = this.getNodeSize();
        let borderRadius = this.node.style.merge('borderRadius');
        const pathStr = `
      M${borderRadius},0
      L${width - borderRadius},0
      C${width - borderRadius},0 ${width},${0} ${width},${borderRadius}
      L${width},${height - borderRadius}
      C${width},${height - borderRadius} ${width},${height} ${
            width - borderRadius
        },${height}
      L${borderRadius},${height}
      C${borderRadius},${height} ${0},${height} ${0},${height - borderRadius}
      L${0},${borderRadius}
      C${0},${borderRadius} ${0},${0} ${borderRadius},${0}
      Z
    `;
        return this.createPath(pathStr);
    }

    //  创建菱形
    createDiamond() {
        let { width, height } = this.getNodeSize();
        let halfWidth = width / 2;
        let halfHeight = height / 2;
        let topX = halfWidth;
        let topY = 0;
        let rightX = width;
        let rightY = halfHeight;
        let bottomX = halfWidth;
        let bottomY = height;
        let leftX = 0;
        let leftY = halfHeight;
        const points = [
            [topX, topY],
            [rightX, rightY],
            [bottomX, bottomY],
            [leftX, leftY],
        ];
        return this.createPolygon(points);
    }

    //  创建平行四边形
    createParallelogram() {
        let { paddingX } = this.node.getPaddingVale();
        paddingX = paddingX || this.node.shapePadding.paddingX;
        let { width, height } = this.getNodeSize();
        const points = [
            [paddingX, 0],
            [width, 0],
            [width - paddingX, height],
            [0, height],
        ];
        return this.createPolygon(points);
    }

    //  创建圆角矩形
    createRoundedRectangle() {
        let { width, height } = this.getNodeSize();
        let halfHeight = height / 2;
        const pathStr = `
      M${halfHeight},0
      L${width - halfHeight},0
      A${height / 2},${height / 2} 0 0,1 ${width - halfHeight},${height} 
      L${halfHeight},${height}
      A${height / 2},${height / 2} 0 0,1 ${halfHeight},${0}
    `;
        return this.createPath(pathStr);
    }

    //  创建八角矩形
    createOctagonalRectangle() {
        let w = 5;
        let { width, height } = this.getNodeSize();
        const points = [
            [0, w],
            [w, 0],
            [width - w, 0],
            [width, w],
            [width, height - w],
            [width - w, height],
            [w, height],
            [0, height - w],
        ];
        return this.createPolygon(points);
    }

    //  创建外三角矩形
    createOuterTriangularRectangle() {
        let { paddingX } = this.node.getPaddingVale();
        paddingX = paddingX || this.node.shapePadding.paddingX;
        let { width, height } = this.getNodeSize();
        const points = [
            [paddingX, 0],
            [width - paddingX, 0],
            [width, height / 2],
            [width - paddingX, height],
            [paddingX, height],
            [0, height / 2],
        ];
        return this.createPolygon(points);
    }

    //  创建内三角矩形
    createInnerTriangularRectangle() {
        let { paddingX } = this.node.getPaddingVale();
        paddingX = paddingX || this.node.shapePadding.paddingX;
        let { width, height } = this.getNodeSize();
        const points = [
            [0, 0],
            [width, 0],
            [width - paddingX / 2, height / 2],
            [width, height],
            [0, height],
            [paddingX / 2, height / 2],
        ];
        return this.createPolygon(points);
    }

    //  创建椭圆
    createEllipse() {
        let { width, height } = this.getNodeSize();
        let halfWidth = width / 2;
        let halfHeight = height / 2;
        const pathStr = `
      M${halfWidth},0
      A${halfWidth},${halfHeight} 0 0,1 ${halfWidth},${height} 
      M${halfWidth},${height} 
      A${halfWidth},${halfHeight} 0 0,1 ${halfWidth},${0} 
    `;
        return this.createPath(pathStr);
    }

    //  创建圆
    createCircle() {
        let { width, height } = this.getNodeSize();
        let halfWidth = width / 2;
        let halfHeight = height / 2;
        const pathStr = `
      M${halfWidth},0
      A${halfWidth},${halfHeight} 0 0,1 ${halfWidth},${height} 
      M${halfWidth},${height} 
      A${halfWidth},${halfHeight} 0 0,1 ${halfWidth},${0} 
    `;
        return this.createPath(pathStr);
    }
}

// 形状列表
export const shapeList = [
    CONSTANTS.SHAPE.RECTANGLE,
    CONSTANTS.SHAPE.DIAMOND,
    CONSTANTS.SHAPE.PARALLELOGRAM,
    CONSTANTS.SHAPE.ROUNDED_RECTANGLE,
    CONSTANTS.SHAPE.OCTAGONAL_RECTANGLE,
    CONSTANTS.SHAPE.OUTER_TRIANGULAR_RECTANGLE,
    CONSTANTS.SHAPE.INNER_TRIANGULAR_RECTANGLE,
    CONSTANTS.SHAPE.ELLIPSE,
    CONSTANTS.SHAPE.CIRCLE,
];
